package study.itwill.common;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.log4j.Logger;

public class HttpHandler {
	
	// Logger 클래스의 인스턴스를 받아온다.
	static Logger logger = Logger.getLogger(HttpHandler.class);
	
	// 기본 인코딩 형식 지정
	private static final String ENC_TYPE = "UTF-8";

	// 기본 접속 제한 시간 (1/1000초 단위 --> 밀리세컨드)
	private static final int TIMEOUT = 30000;

	/** 접속의 기본 정보를 내장하고 있는 객체를 생성하여 리턴 */
	private static HttpClient getClient(String encType) {
		
		logger.debug("=============== method start >> getClient");
		
		// 접속을 하기 위한 기본 환경설정
		HttpParams params = new BasicHttpParams();
		// 웹 통신 프로토콜의 버전을 설정
		params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
				HttpVersion.HTTP_1_1);

		// 접속기능을 하는 객체 생성 <-- 예가 주인공
		HttpClient client = new DefaultHttpClient(params);

		// 접속 제한시간 설정 (30초 / 1초=1000)
		HttpParams p = client.getParams();
		HttpConnectionParams.setConnectionTimeout(p, TIMEOUT);

		// 응답 제한시간 설정
		HttpConnectionParams.setSoTimeout(p, TIMEOUT);

		// 통신에 사용될 인코딩 타입 설정
		if (encType == null) {
			// 값이 없다면 기본값으로 UTF-8 설정
			encType = ENC_TYPE;
		}
		HttpProtocolParams.setContentCharset(p, encType);
		
		logger.debug("=============== method end >> getClient");

		return client;
	}

	/** 웹 서버에 요청을 보내고 응답을 리턴하는 메서드 - 1차 작업 */
	public static InputStream connect(String url, String encType) {
		
		logger.debug("=============== method start >> connect");
		
		// 접속 주소의 앞뒤 공백 제거
		url = url.trim();
		
		// 응답결과가 저장될 객체 --> 리턴대상
		InputStream istream = null;

		// 통신정보 설정
		HttpClient client = HttpHandler.getClient(encType);

		// 접속을 수행하기 위한 객체
		HttpGet httpget = new HttpGet(url);

		try {
			// 요청을 보내고, 응답을 받는다.
			HttpResponse response = client.execute(httpget);

			// 서버의 정상 동작 여부 검사
			int resultCode = response.getStatusLine().getStatusCode();

			if (resultCode == HttpURLConnection.HTTP_OK) {
				// 수신된 응답에서 실 데이터를 추출한다.
				HttpEntity entity = response.getEntity();
				BufferedHttpEntity buffer = new BufferedHttpEntity(entity);

				// 추출한 데이터를 InputStream으로 변환
				istream = buffer.getContent();
			} else {
				// 서버 에러의 원인
				String reason = response.getStatusLine().getReasonPhrase();
				logger.error("------------------------");
				logger.error("서버에러: " + resultCode);
				logger.error("------------------------");
				logger.error(reason);
				logger.error("------------------------");
			}
		} catch (ClientProtocolException e) {
			logger.error("통신처리 에러: " + e.getLocalizedMessage());
			logger.error(e);
		} catch (IOException e) {
			logger.error("응답수신 에러: " + e.getLocalizedMessage());
			logger.error(e);
		} catch (Exception e) {
			logger.error("기타 통신 에러: " + e.getLocalizedMessage());
			logger.error(e);
		} finally {
			// 통신 해제
			client.getConnectionManager().shutdown();
		}
		/********* 통신처리 끝 ********/
		
		logger.debug("=============== method end >> connect");

		return istream;
	}

	/** 기본 인코딩 타입을 사용하도록 재정의된 메서드 */
	public static InputStream connect(String url) {
		
		logger.debug("=============== method start >> connect");
		
		InputStream is = HttpHandler.connect(url, null);
		
		logger.debug("=============== method end >> connect");
		
		return is;
	}
}




